#include "Quad.h"
#include <VertexTypes.h>
#include <fstream>

using namespace DirectX;
// this function loads a file into an Array^
 char* LoadShaderFile(std::string File, int &lenght)
{
    char* FileData = nullptr;

    // open the file
    std::ifstream VertexFile(File, std::ios::in | std::ios::binary | std::ios::ate);
    
    // if open was successful
    if(VertexFile.is_open())
    {
        // find the length of the file
        int Length = (int)VertexFile.tellg();
		lenght = Length;

        // collect the file data
        FileData = new char[Length];
        VertexFile.seekg(0, std::ios::beg);
        VertexFile.read(reinterpret_cast<char*>(FileData), Length);
        VertexFile.close();
    }

    return FileData;
}
Quad::Quad(Game * game)
{
	m_game = game;
}


Quad::~Quad(void)
{
}
struct VERTEX
{
    XMFLOAT3 position;
    XMFLOAT4 color;
};

void Quad::Initialize()
{
	int vsLength, psLength;

	   // load the shader files
    char*  VSFile = LoadShaderFile("Resources\\QuadVS.cso",vsLength);
    char*  PSFile  = LoadShaderFile("Resources\\QuadPS.cso",psLength);

	    // create the shader objects
	HRESULT result;
	result = m_game->GetD3DDevice()->CreateVertexShader(VSFile, vsLength, nullptr, &m_vertexshader);
	if( result != S_OK)
		return;
    result = m_game->GetD3DDevice()->CreatePixelShader(PSFile, psLength, nullptr, &m_pixelshader);
	if( result != S_OK)
		return;
   

	// create a triangle out of vertices
	VERTEX Vertices[4];
    
	Vertices[0].position = XMFLOAT3(-0.5f,  0.5f,0);
	Vertices[1].position = XMFLOAT3( 0.5f,  0.5f,0);
	Vertices[2].position = XMFLOAT3( 0.5f, -0.5f,0);
	Vertices[3].position = XMFLOAT3(-0.5f, -0.5f,0);

	Vertices[0].color = XMFLOAT4(1,1,1,1);
	Vertices[1].color = XMFLOAT4(1,1,1,1);
	Vertices[2].color = XMFLOAT4(1,0,0,0);
	Vertices[3].color = XMFLOAT4(1,1,1,1);

	D3D11_INPUT_ELEMENT_DESC ied[] =
	{
		{ "POSITION",	0, DXGI_FORMAT_R32G32B32_FLOAT,    0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 },
		{ "COLOR",      0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 },
	};

    // create the vertex buffer
    D3D11_BUFFER_DESC bd = {0};
    bd.ByteWidth = sizeof(VERTEX) * ARRAYSIZE(Vertices);
    bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;

    D3D11_SUBRESOURCE_DATA srd = {Vertices, 0, 0};

    m_game->GetD3DDevice()->CreateBuffer(&bd, &srd, &m_vertexbuffer);
	
	result = m_game->GetD3DDevice()->CreateInputLayout(ied, ARRAYSIZE(ied), VSFile, vsLength, &m_inputlayout);
	
	if( result != S_OK)
		return;

	UINT indices[] = 
	{
		0,1,2,
		0,2,3
	};

	
	D3D11_BUFFER_DESC ibd = {0};
	ibd.Usage = D3D11_USAGE_IMMUTABLE;
	ibd.ByteWidth = sizeof(UINT) * 6;
	ibd.BindFlags = D3D11_BIND_INDEX_BUFFER;
	ibd.CPUAccessFlags = 0;
	ibd.MiscFlags = 0;
	ibd.StructureByteStride = 0;
	
	D3D11_SUBRESOURCE_DATA iinit_data;
	iinit_data.pSysMem = indices;
	m_game->GetD3DDevice()->CreateBuffer(&ibd, &iinit_data, &m_indexbuffer);
	m_game->GetGraphicsDevice()->GetDeviceContext()->IASetInputLayout(m_inputlayout);


}

void Quad::Draw()
{

	 // set the shader objects as the active shaders
	m_game->GetGraphicsDevice()->GetDeviceContext()->VSSetShader(m_vertexshader, nullptr, 0);
    m_game->GetGraphicsDevice()->GetDeviceContext()->PSSetShader(m_pixelshader, nullptr, 0);

    // set the vertex buffer
	UINT stride = sizeof(VERTEX);
    UINT offset = 0;
	m_game->GetGraphicsDevice()->GetDeviceContext()->IASetVertexBuffers(0, 1, &m_vertexbuffer, &stride, &offset);
	m_game->GetGraphicsDevice()->GetDeviceContext()->IASetIndexBuffer(m_indexbuffer,DXGI_FORMAT_R32_UINT, 0);


    // set the primitive topology
    m_game->GetGraphicsDevice()->GetDeviceContext()->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);

    // draw indexed quad with 6 indices with start at index 0 and base vertex location at 0
	m_game->GetGraphicsDevice()->GetDeviceContext()->DrawIndexed(6,0,0);

    
}